﻿using System;
using System.Globalization;
using System.Text;

namespace Mono.Cecil.Cil
{
	// Token: 0x0200011E RID: 286
	public sealed class Instruction
	{
		// Token: 0x170002D7 RID: 727
		// (get) Token: 0x06000B06 RID: 2822 RVA: 0x00031490 File Offset: 0x0002F690
		// (set) Token: 0x06000B07 RID: 2823 RVA: 0x00005EF3 File Offset: 0x000040F3
		public int Offset
		{
			get
			{
				return this.offset;
			}
			set
			{
				this.offset = value;
			}
		}

		// Token: 0x170002D8 RID: 728
		// (get) Token: 0x06000B08 RID: 2824 RVA: 0x000314A8 File Offset: 0x0002F6A8
		// (set) Token: 0x06000B09 RID: 2825 RVA: 0x00005EFD File Offset: 0x000040FD
		public OpCode OpCode
		{
			get
			{
				return this.opcode;
			}
			set
			{
				this.opcode = value;
			}
		}

		// Token: 0x170002D9 RID: 729
		// (get) Token: 0x06000B0A RID: 2826 RVA: 0x000314C0 File Offset: 0x0002F6C0
		// (set) Token: 0x06000B0B RID: 2827 RVA: 0x00005F07 File Offset: 0x00004107
		public object Operand
		{
			get
			{
				return this.operand;
			}
			set
			{
				this.operand = value;
			}
		}

		// Token: 0x170002DA RID: 730
		// (get) Token: 0x06000B0C RID: 2828 RVA: 0x000314D8 File Offset: 0x0002F6D8
		// (set) Token: 0x06000B0D RID: 2829 RVA: 0x00005F11 File Offset: 0x00004111
		public Instruction Previous
		{
			get
			{
				return this.previous;
			}
			set
			{
				this.previous = value;
			}
		}

		// Token: 0x170002DB RID: 731
		// (get) Token: 0x06000B0E RID: 2830 RVA: 0x000314F0 File Offset: 0x0002F6F0
		// (set) Token: 0x06000B0F RID: 2831 RVA: 0x00005F1B File Offset: 0x0000411B
		public Instruction Next
		{
			get
			{
				return this.next;
			}
			set
			{
				this.next = value;
			}
		}

		// Token: 0x06000B10 RID: 2832 RVA: 0x00005F25 File Offset: 0x00004125
		internal Instruction(int offset, OpCode opCode)
		{
			this.offset = offset;
			this.opcode = opCode;
		}

		// Token: 0x06000B11 RID: 2833 RVA: 0x00005F3D File Offset: 0x0000413D
		internal Instruction(OpCode opcode, object operand)
		{
			this.opcode = opcode;
			this.operand = operand;
		}

		// Token: 0x06000B12 RID: 2834 RVA: 0x00031508 File Offset: 0x0002F708
		public int GetSize()
		{
			int size = this.opcode.Size;
			switch (this.opcode.OperandType)
			{
			case OperandType.InlineBrTarget:
			case OperandType.InlineField:
			case OperandType.InlineI:
			case OperandType.InlineMethod:
			case OperandType.InlineSig:
			case OperandType.InlineString:
			case OperandType.InlineTok:
			case OperandType.InlineType:
			case OperandType.ShortInlineR:
				return size + 4;
			case OperandType.InlineI8:
			case OperandType.InlineR:
				return size + 8;
			case OperandType.InlineSwitch:
				return size + (1 + ((Instruction[])this.operand).Length) * 4;
			case OperandType.InlineVar:
			case OperandType.InlineArg:
				return size + 2;
			case OperandType.ShortInlineBrTarget:
			case OperandType.ShortInlineI:
			case OperandType.ShortInlineVar:
			case OperandType.ShortInlineArg:
				return size + 1;
			}
			return size;
		}

		// Token: 0x06000B13 RID: 2835 RVA: 0x000315BC File Offset: 0x0002F7BC
		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			Instruction.AppendLabel(stringBuilder, this);
			stringBuilder.Append(':');
			stringBuilder.Append(' ');
			stringBuilder.Append(this.opcode.Name);
			bool flag = this.operand == null;
			string result;
			if (flag)
			{
				result = stringBuilder.ToString();
			}
			else
			{
				stringBuilder.Append(' ');
				OperandType operandType = this.opcode.OperandType;
				OperandType operandType2 = operandType;
				if (operandType2 <= OperandType.InlineString)
				{
					if (operandType2 != OperandType.InlineBrTarget)
					{
						if (operandType2 != OperandType.InlineString)
						{
							goto IL_10C;
						}
						stringBuilder.Append('"');
						stringBuilder.Append(this.operand);
						stringBuilder.Append('"');
						goto IL_125;
					}
				}
				else
				{
					if (operandType2 == OperandType.InlineSwitch)
					{
						Instruction[] array = (Instruction[])this.operand;
						for (int i = 0; i < array.Length; i++)
						{
							bool flag2 = i > 0;
							if (flag2)
							{
								stringBuilder.Append(',');
							}
							Instruction.AppendLabel(stringBuilder, array[i]);
						}
						goto IL_125;
					}
					if (operandType2 != OperandType.ShortInlineBrTarget)
					{
						goto IL_10C;
					}
				}
				Instruction.AppendLabel(stringBuilder, (Instruction)this.operand);
				goto IL_125;
				IL_10C:
				stringBuilder.Append(Convert.ToString(this.operand, CultureInfo.InvariantCulture));
				IL_125:
				result = stringBuilder.ToString();
			}
			return result;
		}

		// Token: 0x06000B14 RID: 2836 RVA: 0x00005F55 File Offset: 0x00004155
		private static void AppendLabel(StringBuilder builder, Instruction instruction)
		{
			builder.Append("IL_");
			builder.Append(instruction.offset.ToString("x4"));
		}

		// Token: 0x06000B15 RID: 2837 RVA: 0x000316F8 File Offset: 0x0002F8F8
		public static Instruction Create(OpCode opcode)
		{
			bool flag = opcode.OperandType != OperandType.InlineNone;
			if (flag)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, null);
		}

		// Token: 0x06000B16 RID: 2838 RVA: 0x00031730 File Offset: 0x0002F930
		public static Instruction Create(OpCode opcode, TypeReference type)
		{
			bool flag = type == null;
			if (flag)
			{
				throw new ArgumentNullException("type");
			}
			bool flag2 = opcode.OperandType != OperandType.InlineType && opcode.OperandType != OperandType.InlineTok;
			if (flag2)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, type);
		}

		// Token: 0x06000B17 RID: 2839 RVA: 0x00031788 File Offset: 0x0002F988
		public static Instruction Create(OpCode opcode, CallSite site)
		{
			bool flag = site == null;
			if (flag)
			{
				throw new ArgumentNullException("site");
			}
			bool flag2 = opcode.Code != Code.Calli;
			if (flag2)
			{
				throw new ArgumentException("code");
			}
			return new Instruction(opcode, site);
		}

		// Token: 0x06000B18 RID: 2840 RVA: 0x000317D4 File Offset: 0x0002F9D4
		public static Instruction Create(OpCode opcode, MethodReference method)
		{
			bool flag = method == null;
			if (flag)
			{
				throw new ArgumentNullException("method");
			}
			bool flag2 = opcode.OperandType != OperandType.InlineMethod && opcode.OperandType != OperandType.InlineTok;
			if (flag2)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, method);
		}

		// Token: 0x06000B19 RID: 2841 RVA: 0x0003182C File Offset: 0x0002FA2C
		public static Instruction Create(OpCode opcode, FieldReference field)
		{
			bool flag = field == null;
			if (flag)
			{
				throw new ArgumentNullException("field");
			}
			bool flag2 = opcode.OperandType != OperandType.InlineField && opcode.OperandType != OperandType.InlineTok;
			if (flag2)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, field);
		}

		// Token: 0x06000B1A RID: 2842 RVA: 0x00031884 File Offset: 0x0002FA84
		public static Instruction Create(OpCode opcode, string value)
		{
			bool flag = value == null;
			if (flag)
			{
				throw new ArgumentNullException("value");
			}
			bool flag2 = opcode.OperandType != OperandType.InlineString;
			if (flag2)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, value);
		}

		// Token: 0x06000B1B RID: 2843 RVA: 0x000318D0 File Offset: 0x0002FAD0
		public static Instruction Create(OpCode opcode, sbyte value)
		{
			bool flag = opcode.OperandType != OperandType.ShortInlineI && opcode != OpCodes.Ldc_I4_S;
			if (flag)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, value);
		}

		// Token: 0x06000B1C RID: 2844 RVA: 0x00031918 File Offset: 0x0002FB18
		public static Instruction Create(OpCode opcode, byte value)
		{
			bool flag = opcode.OperandType != OperandType.ShortInlineI || opcode == OpCodes.Ldc_I4_S;
			if (flag)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, value);
		}

		// Token: 0x06000B1D RID: 2845 RVA: 0x00031960 File Offset: 0x0002FB60
		public static Instruction Create(OpCode opcode, int value)
		{
			bool flag = opcode.OperandType != OperandType.InlineI;
			if (flag)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, value);
		}

		// Token: 0x06000B1E RID: 2846 RVA: 0x0003199C File Offset: 0x0002FB9C
		public static Instruction Create(OpCode opcode, long value)
		{
			bool flag = opcode.OperandType != OperandType.InlineI8;
			if (flag)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, value);
		}

		// Token: 0x06000B1F RID: 2847 RVA: 0x000319D8 File Offset: 0x0002FBD8
		public static Instruction Create(OpCode opcode, float value)
		{
			bool flag = opcode.OperandType != OperandType.ShortInlineR;
			if (flag)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, value);
		}

		// Token: 0x06000B20 RID: 2848 RVA: 0x00031A14 File Offset: 0x0002FC14
		public static Instruction Create(OpCode opcode, double value)
		{
			bool flag = opcode.OperandType != OperandType.InlineR;
			if (flag)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, value);
		}

		// Token: 0x06000B21 RID: 2849 RVA: 0x00031A50 File Offset: 0x0002FC50
		public static Instruction Create(OpCode opcode, Instruction target)
		{
			bool flag = target == null;
			if (flag)
			{
				throw new ArgumentNullException("target");
			}
			bool flag2 = opcode.OperandType != OperandType.InlineBrTarget && opcode.OperandType != OperandType.ShortInlineBrTarget;
			if (flag2)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, target);
		}

		// Token: 0x06000B22 RID: 2850 RVA: 0x00031AA8 File Offset: 0x0002FCA8
		public static Instruction Create(OpCode opcode, Instruction[] targets)
		{
			bool flag = targets == null;
			if (flag)
			{
				throw new ArgumentNullException("targets");
			}
			bool flag2 = opcode.OperandType != OperandType.InlineSwitch;
			if (flag2)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, targets);
		}

		// Token: 0x06000B23 RID: 2851 RVA: 0x00031AF4 File Offset: 0x0002FCF4
		public static Instruction Create(OpCode opcode, VariableDefinition variable)
		{
			bool flag = variable == null;
			if (flag)
			{
				throw new ArgumentNullException("variable");
			}
			bool flag2 = opcode.OperandType != OperandType.ShortInlineVar && opcode.OperandType != OperandType.InlineVar;
			if (flag2)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, variable);
		}

		// Token: 0x06000B24 RID: 2852 RVA: 0x00031B4C File Offset: 0x0002FD4C
		public static Instruction Create(OpCode opcode, ParameterDefinition parameter)
		{
			bool flag = parameter == null;
			if (flag)
			{
				throw new ArgumentNullException("parameter");
			}
			bool flag2 = opcode.OperandType != OperandType.ShortInlineArg && opcode.OperandType != OperandType.InlineArg;
			if (flag2)
			{
				throw new ArgumentException("opcode");
			}
			return new Instruction(opcode, parameter);
		}

		// Token: 0x040005CE RID: 1486
		internal int offset;

		// Token: 0x040005CF RID: 1487
		internal OpCode opcode;

		// Token: 0x040005D0 RID: 1488
		internal object operand;

		// Token: 0x040005D1 RID: 1489
		internal Instruction previous;

		// Token: 0x040005D2 RID: 1490
		internal Instruction next;
	}
}
